/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pl.abstractvoid.gui;

import java.math.BigDecimal;
import java.math.MathContext;
import java.util.ArrayList;
import javax.swing.table.AbstractTableModel;
import pl.abstractvoid.datamodel.parameters.ParameterTable;
import pl.abstractvoid.languages.LanguageProvider;

/**
 * Responsible for communication between the table components and the program
 * data model. Allows for bi-directional communication: changed in tabular
 * data is reflected in the distribution data and vice versa. This way when
 * new data is generated by running an R script, the component can load new
 * values directly from the altered objects.
 * @author Wojciech Szałapski
 * @author Ivo Zieliński
 */
public class ParameterTableModel extends AbstractTableModel {

    private String[] visibleParameterNames;
    private String[] parameterNames;
    private String tableName;
    private ParameterTable parameterTable;
    private String visibleTableName;

    public ParameterTableModel(ParameterTable parameterTable) {
        this.parameterTable = parameterTable;
        visibleParameterNames = parameterTable.getVisibleParameterNames();
        tableName = parameterTable.getTableName();
        parameterNames = parameterTable.getParameterNames();
        visibleTableName = parameterTable.getTableName();
    }

    @Override
    public int getColumnCount() {
        return visibleParameterNames.length;
    }

    public String[] getColumnNames() {
        return visibleParameterNames;
    }

    public void setColumnNames(String[] columnNames) {
        this.visibleParameterNames = columnNames;

    }

    public ParameterTable getData() {
        return parameterTable;
    }

    public void setData(ParameterTable parameterTable) {
        this.parameterTable = parameterTable;
    }

    @Override
    public int getRowCount() {
        return parameterTable.getParameterValues().get(0).size();
    }

    @Override
    public Object getValueAt(int row, int col) {
        int decimalPlaces = (int) MainFrame.roundingMode;
        double d = parameterTable.getParameterValues().get(col).get(row);
        if (d >= 10) {
            decimalPlaces += (int) Math.floor(Math.log10(d));
        }
        BigDecimal bd = new BigDecimal(d);
        bd = bd.round(new MathContext(decimalPlaces));
        return bd.doubleValue();
    }

    @Override
    public String getColumnName(int col) {
        return visibleParameterNames[col];
    }

    @Override
    public void setValueAt(Object value, int rowIndex, int columnIndex) {
        ArrayList<Double> kolumna = parameterTable.getParameterValues().get(columnIndex);
        try {
            double newValue = Double.parseDouble((String) value);
            kolumna.set(rowIndex, newValue);
        } catch (NumberFormatException nfe) {
            System.out.println(LanguageProvider.getInstance().getString("insertANumber"));
        }
    }

    @Override
    public boolean isCellEditable(int row, int col) {
        return true;
    }

    public String[] getVisibleParameterNames() {
        return visibleParameterNames;
    }

    public String[] getParameterNames() {
        return parameterNames;
    }

    public String getTableName() {
        return tableName;
    }

    public ParameterTable getParameterTable() {
        return parameterTable;
    }

    public String getVisibleTableName() {
        return visibleTableName;
    }

    public void removeRows(int amount, boolean fromTop) {
        ArrayList<ArrayList<Double>> tabele = parameterTable.getParameterValues();
        for (ArrayList<Double> kolumna : tabele) {
            if (fromTop) {
                for (int i = 0; i < amount; i++) {
                    kolumna.remove(0);
                }
            } else {
                for (int i = 0; i < amount; i++) {
                    kolumna.remove(kolumna.size() - 1);
                }
            }
        }
    }

    public void removeRows(int[] rows) {
        ArrayList<ArrayList<Double>> tabele = parameterTable.getParameterValues();
        for (ArrayList<Double> kolumna : tabele) {
            for (int i = 0; i < rows.length; i++) {
                kolumna.remove(rows[i] - i);
            }
        }
    }

    public void addRows(int amount, boolean fromTop) {
        ArrayList<ArrayList<Double>> tabele = parameterTable.getParameterValues();
        for (ArrayList<Double> kolumna : tabele) {
            if (fromTop) {
                for (int i = 0; i < amount; i++) {
                    kolumna.add(0, 0d);
                }
            } else {
                for (int i = 0; i < amount; i++) {
                    kolumna.add(0d);
                }
            }
        }
    }
}
